const path = require('path') // path: nodeJS里面的基本包
const VueLoaderPlugin = require('vue-loader/lib/plugin') //  使用vue-loader需引入
const HtmlWebpackPlugin = require('html-webpack-plugin') //  生成html文件插件
const webpack = require('webpack') //   下文调用，判断环境等操作
const ExtractPlugin = require('extract-text-webpack-plugin') // 将非js文件提取出来打包

const isDev = process.env.NODE_ENV === 'development' // 判断当前环境是否为开发环境

const config = {
  // 设置编译目标，web平台
  target: 'web',

  // 入口  __dirname根路径   与第二参数拼接，形成绝对路径
  entry: path.join(__dirname, 'src/index.js'),

  // 出口  将入口文件和相关依赖全打包为浏览器可直接运行的js代码
  output: {
    filename: 'bundle.[hash:8].js', //  开发环境文件名不能用chunkhash
    path: path.join(__dirname, 'dist')
  },

  plugins: [
    // 使用框架所必须插件   用来判断环境，可以在文件中直接使用process.env.NODE_ENV === 'xxx'的方式
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: isDev ? '"development"' : '"production"'
      }
    }),
    new VueLoaderPlugin(), //  使用vue-loader需引入
    new HtmlWebpackPlugin() //  使用html-webpack-plugin
  ],

  // 语法规则
  module: {
    rules: [{
        test: /\.vue$/, //  检测文件类型  正则    .需要转义
        loader: 'vue-loader' //  用vue-loader来处理.vue文件
      },
      {
        test: /\.jsx$/,
        loader: 'babel-loader'
      },
      // {
      //   test: /\.css$/,
      //   // 使用use来规定是插入到html文件中还是外部引用 
      //   use: [
      //     'style-loader', //  插入到html
      //     'css-loader'
      //   ]
      // },
      // {
      //   test: /\.styl(us)?$/,
      //   use: [
      //     'style-loader',
      //     'css-loader',
      //     {
      //       loader: 'postcss-loader',
      //       options: {
      //         sourceMap: true //  stylus-loader会生成sourceMap，postcss-loader直接用它生成的sourceMap，可以使编译更快
      //       }
      //     },
      //     'stylus-loader' //  一层一层往上扔    每个loader只关心自己那一部分    stylus-loader只处理styl代码，处理完成为css代码，然后扔出，让其它的loader进行操作
      //   ]
      // },
      {
        test: /\.(gif|jpg|jpeg|png|svg)$/,
        use: [
          // 以对象的方式配置loader，通过options传递参数，指定url-loader的操作方式
          {
            loader: 'url-loader', //  将图片转换为base64代码，可直接写入到js里面，而不用创建新的文件    封装了style-loader
            options: {
              limit: 1024, // 不超过1024大小的就应用规则
              name: '[name].abcd.[ext]' //  输出的名字  前面自定义，ext为原本文件后缀格式
            }
          }
        ]
      }
    ]
  }
}

// 不同环境变量更改
if (isDev) {
  // 方便在浏览器中进行调试
  config.devtool = '#cheap-module-eval-source-map'

  // 开发环境下stylus的配置
  config.module.rules.push({
    test: /\.styl(us)?$/,
    use: [
      'style-loader',
      'css-loader',
      {
        loader: 'postcss-loader',
        options: {
          sourceMap: true //  stylus-loader会生成sourceMap，postcss-loader直接用它生成的sourceMap，可以使编译更快
        }
      },
      'stylus-loader' //  一层一层往上扔    每个loader只关心自己那一部分    stylus-loader只处理styl代码，处理完成为css代码，然后扔出，让其它的loader进行操作
    ]
  })

  // devServer是一种服务，需要配置
  config.devServer = {
      port: 8000, //  端口
      host: '0.0.0.0', // 更自由，手机调试也可以访问到本地
      overlay: {
        errors: true //  若编译，直接抛出，显示到网页上
      },
      hot: true //  若修改一个组件的代码，只会渲染当前组件，不会全部渲染   即热更新
        // open: true  //  自动打开浏览器
    },

    // 若要实现hot能力，还需要增加plugins
    config.plugins.push(
      new webpack.HotModuleReplacementPlugin(), //  热更新插件
      new webpack.NoEmitOnErrorsPlugin() //   将不需要的信息隐藏
    )
} else {
  // 打包类库文件
  config.entry = {
    app: path.join(__dirname, 'src/index.js'),
    vendor: ['vue'] //  打包的框架及包     打包为单独的文件   vendor.js
  }

  // 生产环境输出文件名
  config.output.filename = '[name].[chunkhash:8].js'

  // 生产环境下stylus的配置
  config.module.rules.push({
    test: /\.styl(us)?$/,
    use: ExtractPlugin.extract({
      fallback: 'style-loader',
      use: [
        'css-loader',
        {
          loader: 'postcss-loader',
          options: {
            sourceMap: true //  stylus-loader会生成sourceMap，postcss-loader直接用它生成的sourceMap，可以使编译更快
          }
        },
        'stylus-loader' //  一层一层往上扔    每个loader只关心自己那一部分    stylus-loader只处理styl代码，处理完成为css代码，然后扔出，让其它的loader进行操作
      ]
    })
  })

  config.plugins.push(
    new ExtractPlugin('style.[hash:8].css'), // 输出的文件添加hash值
  )

  // 打包类库文件
  config.optimization = {
    splitChunks: {
      cacheGroups: {
        commons: {
          chunks: 'initial',
          minChunks: 2,
          maxInitialRequests: 5,
          minSize: 0
        },
        vendor: {
          test: /node_modules/,
          chunks: 'initial',
          name: 'vendor',
          priority: 10,
          enforce: true
        }
      }
    }
  }
}

module.exports = config